package ws

import (
	"context"
	"coolcar/v1/car/mq"
	"github.com/gorilla/websocket"
	"go.uber.org/zap"
	"net/http"
)

func Handler(u *websocket.Upgrader, sub mq.Subscriber, Sugar *zap.SugaredLogger) http.HandlerFunc {
	return func(w http.ResponseWriter, req *http.Request) {
		c, err := u.Upgrade(w, req, nil)
		if err != nil {
			Sugar.Warn("failed to upgrade: %v", err)
		}
		defer c.Close()
		msgs, cleanUp, err := sub.Subscribe(context.Background())
		defer cleanUp()
		if err != nil {
			Sugar.Error("failed to subscribe: %v", err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		done := make(chan struct{})
		go func() {
			for {
				_, _, err := c.ReadMessage()
				if err != nil {
					if !websocket.IsCloseError(err, websocket.CloseGoingAway, websocket.CloseNormalClosure) {
						Sugar.Warn("unexpected read error: %v", err)
					}
					done <- struct{}{}
					break
				}
			}
		}()

		for {
			select {
			case msg := <-msgs:
				err := c.WriteJSON(msg)
				if err != nil {
					Sugar.Warn("failed to write message: %v", err)
				}
			case <-done:
				return
			}
		}

	}
}
